﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    class Spell_BleedingWounds : Buff
    {
        private int CurrentDamage = 10;
        
        //260 Damage [int / 2] (Rank 1 LVL 5)
        //546 Damage [int / 2] (Rank 2 LVL 22)
        private int getMightMaxDamage(SpellIcon sIcon)
        {
            if (sIcon.Name.IndexOf("Rank 2") > -1)
                return 42;
            else
                return 20;
        }


        //468
        private int MentMaxDamage = 36;


        private int CalcMaxDamage = 1;

        private int incrementAmount = 15;

        public Spell_BleedingWounds() 
        {
            spellTimer.Interval = 2000;
            minutesLeft = -2;
            ticksLeft = 13;
            saveBuff = false;
        }
        public void AddDamage()
        {
            if (CurrentDamage < CalcMaxDamage)
                CurrentDamage = CurrentDamage + incrementAmount;
            if (CurrentDamage > CalcMaxDamage)
                CurrentDamage = CalcMaxDamage;
        }
        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, true, out MapItemsWithin12) == false)
                return;


            int totalDotAmount = 0;
            if (spellIcon.Skill == "Might")
            {
                totalDotAmount = this.getMightMaxDamage(spellIcon) * ticksLeft;
                totalDotAmount = SkillManager.AdjustForCombat(System.Convert.ToInt32(CastingCreatureLevel), totalDotAmount, CastingCreatureInt / 2);
                totalDotAmount = CreatureBase.calculateDamageAfterArmor(totalDotAmount, TargetCreatureBase.ArmorTotal);
            }
            else if (spellIcon.Skill == "Mentality")
            {
                totalDotAmount = MentMaxDamage * ticksLeft;
                totalDotAmount = SkillManager.AdjustForCombat(CastingCreatureLevel, totalDotAmount, CastingCreatureInt);
                totalDotAmount = TargetCreatureBase.CalculateGetSpellDamagePerResists(totalDotAmount, spellIcon.Skill);
            }

            CalcMaxDamage = totalDotAmount / ticksLeft;
            incrementAmount = CalcMaxDamage / (ticksLeft / 2);

            int currentDamage = CurrentDamage;
            if (base.overwrittenBuff != null)
            {
                Spell_BleedingWounds bw = (Spell_BleedingWounds)base.overwrittenBuff;
                currentDamage = bw.CurrentDamage;
            }

            CurrentDamage = currentDamage;

            foreach (MapItem mapitem in MapItemsWithin12)
            {
                foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                {
                    if (creaturebase is Character)
                    {
                        Character character = (Character)creaturebase;
                        //character.PlaySound("FireBolt", MyCreatureBase.MapX, MyCreatureBase.MapY);
                    }
                }
            }

            TargetCreatureBase.buffManager.UpdateBuffs();

            spellTimer.Start();
        }
        protected override void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

            lock (lockitem.LockObj)
            {
                //CHECK IF WE'RE IN A VALID STATE TO CONTINUE EXECUTION/////////////////////////

                //System.Reflection.MethodBase currentMethodBase = System.Reflection.MethodBase.GetCurrentMethod();
                //Delegate currentMethodDelegate = Delegate.CreateDelegate(currentMethodBase.GetType(), this, currentMethodBase.Name);

                //Create a delegate for this method incase it cant be run right now
                Action<object, ElapsedEventArgs> thisMethod = (Action<object, ElapsedEventArgs>)SpellTimer_Expired;
                //Record this method's arguments
                Object[] thisMethodArgs = { source, e };
                //Pass the delegate and args when we check if we're mid map transfer. If yes, they will be recorded and run again automatically.
                if (TargetCreatureBase.isChangingMaps(thisMethod, thisMethodArgs) == true)
                    return;

                //A map transfer happened, but its already complete. Immediately re-run this method on a different thread. 
                //We need to use a different thread because otherwise the current thread would lock 2 maps possibly resulting in a deadlock.
                if (TargetCreatureBase.MapID != lockitem.MapID)
                {
                    thisMethod.BeginInvoke(source, e, null, null);
                    return;
                }
                //STATE IS VALID, CONTINUE EXECUTION///////////////////////////////////////////

                //This buff has been removed, do nothing
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                if (TargetCreatureBase.HP < 1)
                {
                    RemoveSpell(true, false);
                    return;
                }

                Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
                List<MapItem> MapItemsWithin8 = new List<MapItem>();
                List<Character> CharactersWithin8 = new List<Character>();
                MapItem CurrentMapItem = null;
                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 8 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 8)
                    {
                        MapItemsWithin8.Add(mapitem);
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character)
                                CharactersWithin8.Add((Character)creaturebase);
                        }
                    }
                    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY)
                        CurrentMapItem = mapitem;
                }

                
                TargetCreatureBase.InflictDamage(CurrentDamage,CastingCharacterID);
                TargetCreatureBase.Update_Character();

                if (spellIcon.Skill == "Might")
                {
                    Managers.GameHandler.TrySendMessage(CastingCharacterID, "" + TargetCreatureBase.Name + " bleeds! (" + CurrentDamage.ToString() + ")", "spelldamage");
                    TargetCreatureBase.SendMessage("You bleed! (" + CurrentDamage.ToString() + ")", "spelloffense");
                }

                else if (spellIcon.Skill == "Mentality")
                {
                    Managers.GameHandler.TrySendMessage(CastingCharacterID, "" + TargetCreatureBase.Name + " burns! (" + CurrentDamage.ToString() + ")", "spelldamage");
                    TargetCreatureBase.SendMessage("You burn! (" + CurrentDamage.ToString() + ")", "spelloffense");
                }
                
                if (TargetCreatureBase.HP < 1)
                {
                    Managers.GameHandler.TrySendMessage(CastingCharacterID, "You have SLAIN " + TargetCreatureBase.Name + "!", "slay");

                    if (!(TargetCreatureBase is Character))
                        CurrentMapItem.CreaturesBases.Remove(TargetCreatureBase);

                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                        {
                            if (TargetCreatureBase.HP < 1)
                                character.AddMapItem(CurrentMapItem);
                            else
                                character.UpdateCreatureBaseHp(TargetCreatureBase);
                        }
                    }
                }

                if (ticksLeft > 0 && TargetCreatureBase.HP > 0)
                {
                    ticksLeft--;
                    spellTimer.Start();
                }
                else
                    RemoveSpell(true, true);
            
            }//End Lock

        }
    }
}
